
#ifndef LTLST_H
#define LTLST_H

#include "ltdb.h"
#include "mem.h"

// typedef struct ltlst_node_struct ltlst_node_t;
// struct ltlst_node_struct
// {
//     ltlst_node_t*   prev;
//     ltlst_node_t*   next;
//     void*           data;
// };
// 
// 
// typedef struct ltlst_base_struct ltlst_base_t;
// struct ltlst_base_struct
// {
//     uint32          count;
//     ltlst_node_t*   start;
//     ltlst_node_t*   end;
// 
//     mem_obj_t*      mo;
// };


#define LT_LST_BASE(type) \
struct type##_base \
{\
    uint32  count;\
    type*   start;\
    type*   end;\
}


#define LT_LST_LINK(type) \
struct type##_link \
{\
    type*   prev; \
    type*   next; \
}  link

#define LT_LST_INIT(base) \
{\
    base.count = 0;\
    base.start = NULL;\
    base.end = NULL;\
}

#define LT_LST_ADD_FIRST(base, node) \
{\
    if (base.count == 0)\
    {\
        base.start = node;\
        base.end = node;\
        node->link.prev = NULL;\
        node->link.next = NULL;\
    }\
    else\
    {\
        base.start->prev = node;\
        node->link.next = base.start;\
        node->link.prev = NULL;\
        base.start = node;\
    }\
    base.count ++;\
}

#define LT_LST_ADD_LAST(base, node) \
{\
    if (base.count == 0)\
    {\
        base.start = node;\
        base.end = node;\
        node->link.prev = NULL;\
        node->link.next = NULL;\
    }\
    else\
    {\
        base.end->link.next = node;\
        node->link.prev = base.end;\
        node->link.next = NULL;\
        base.end = node;\
    }\
    base.count ++;\
}

#define LT_LST_INSERT_BEFORE(base, node, new_node) \
{\
    base.count ++;\
    new_node->link.prev = node->link.prev;\
    new_node->link.next = node;\
    node->link.prev = new_node;\
}

#define LT_LST_INSERT_AFTER(base, node, new_node) \
{\
    base.count ++;\
    new_node->link.next = node->link.next;\
    new_node->link.prev = node;\
    node->link.next = new_node;\
}

#define LT_LST_GET_FIRST(base) \
    (base.start)

#define LT_LST_GET_LAST(base) \
    (base.end)

#define LT_LST_GET_LEN(base) \
    (base.count)

#define LT_LST_REMOVE(base, node) \
{\
    base.count --;\
    node->link.prev->link.next = node->link.next;\
    node->link.next->link.prev = node->link.prev;\
}

#define LT_LST_GET_NEXT(node) \
    (node->link.next)

#define LT_LST_GET_PREV(node) \
    (node->link.prev)

#endif // #ifndef LTLST_H


